﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using System.Web.Profile;
using System.Xml.Linq;
using ClientApp.Models;
using CommonApp;
using CommonApp.Models;
using CommonApp.Models;
using IBS.Bll;
using IBS.Bll.Accounts;
using IBS.Bll.Authority;
using IBS.Bll.Cards;
using IBS.Bll.KnowledgeBase;
using IBS.Bll.Payments;
using IBS.Bll.Security;
using IBS.Bll.Transfers;
using IBS.Dal;
using IBS.Model;
using IBS.ServiceContracts;

namespace ClientApp.Controllers
{


    public class PaymentXmlBuilder
    {
        public string PaymentDetailHtml(Payment paymentForDetail, string cardNumber)
        {
            var payment = XDocument.Parse("<payment>" + paymentForDetail.PaymentDetailTemplate + "</payment>");
            var res = from field in payment.Descendants("field")
                      select new XElement("div", new XAttribute("style", "padding: 5px; margin: 5px"),
                                          new XElement("label", field.Attribute("display").Value),
                                          new XElement("input", new XAttribute("value", field.Value),
                                                       new XAttribute("type", "text"),
                                                        new XAttribute("error", field.Attribute("error").Value),
                                                       new XAttribute("regexp", field.Attribute("regexp").Value)));

            var sBuilder = new StringBuilder();
            res.ToList().ForEach(s => sBuilder.Append(s));
            sBuilder.Append("<tr style='padding: 5px; margin: 5px'><label id='validateSummary' style='color:red'/></tr>");
            sBuilder.AppendFormat("<input type='hidden' name='paymentId' value='{0}' />", paymentForDetail.Id);
            sBuilder.AppendFormat("<input type='hidden' name='cardNumber' value='{0}'/>", cardNumber);
            sBuilder.AppendFormat("<tr style='padding: 5px; margin: 5px'><td><label>Currency</label></td><td><select form='pay_form' name='currency'><option value='BYR'>BYR</option><option 'USD'>USD</option></select></td></tr>");
            sBuilder.AppendFormat("<tr style='padding: 5px; margin: 5px'><td><label>Amount</label></td><td><input type='text' name='amount' /></td></tr>");
            //  sBuilder.Append("<input type='submit' onclick='return validate();'/>");

            return sBuilder.ToString();
        }

        public object PaymentDetailJSON(Payment paymentForDetail, string cardNumber)
        {
            var template = @"[{fieldLabel: , regex: , regexText: }]";

            var payment = XDocument.Parse("<payment>" + paymentForDetail.PaymentDetailTemplate + "</payment>");
            var res = from field in payment.Descendants("field")
                      select new
                      {
                          fieldLabel = field.Attribute("display").Value,
                          name = "",
                          value = field.Value,
                          //value = field.Value,
                          regex = field.Attribute("regexp").Value,
                          regexText = field.Attribute("error").Value,
                          hidden = false
                      };
            var result = res.ToList();
            result.Add(new
            {
                fieldLabel = "",
                name = "paymentId",
                value = paymentForDetail.Id.ToString(),
                regex = "",
                regexText = "",
                hidden = true
            });
            result.Add(new
            {
                fieldLabel = "",
                name = "cardNumber",
                value = cardNumber,
                regex = "",
                regexText = "",
                hidden = true
            });

            return result;
        }

        public string PaymentsTreeXml(IEnumerable<Payment> payments)
        {
            StringBuilder stringBuilder = new StringBuilder("<xml>");
            payments.Select(p => "<payment>" + p.PaymentDetailTemplate + "<id>" + p.Id + "</id></payment>").ToList().ForEach(p => stringBuilder.Append(p));
            stringBuilder.Append("</xml>");
            var paymentsXml = stringBuilder.ToString();
            var eripPayments = XDocument.Parse(paymentsXml);
            var result = from i in eripPayments.Descendants("payment")
                         group i by new { company = i.Element("company").Value } into g
                         select new XElement("company", new XAttribute("text", g.Key.company),
                         from p in g
                         select new XElement("payment", new XAttribute("id", p.Element("id").Value),
                             new XAttribute("text", p.Element("title").Value)));
            var sBuilder = new StringBuilder();
            // sBuilder.Append("<xml>");
            foreach (var xElement in result)
            {
                sBuilder.Append(xElement);
            }
            //sBuilder.Append("</xml>");
            return sBuilder.ToString();
        }
    }

    //[Authorize(Roles = "user")]
    public class PaymentsController : Controller
    {
        private IAuthorityService authorityService;
        private IKnowledgeBaseService knowledgeBaseService;
        private ICardService cardService;
        private readonly ITransferService _transferService;
        private IPaymentService paymentService;
        private IAccountService accountService;
        private readonly OperationStep[] steps = new[]
                                           {
                                               new OperationStep { Uid="cardsMenuItem", Name = "Cards", GoTo = "/Payments"},
                                               new OperationStep
                                               { 
                                                   Uid="paymentMenuItem", 
                                                   Name = "Payment selection",
                                                   IsVisible = false,
                                                   GoTo = "/Payments/SelectPayment"
                                                   
                                               },
                                                new OperationStep
                                                             {
                                                                 Uid = "paymentDetailMenuItem",
                                                                 Name = "Pay form",
                                                                 IsVisible = false,
                                                                 GoTo = "/Payments/Detail"
                                                             },
                                                               new OperationStep
                                                             {
                                                                 Uid = "paymentStatementMenuItem",
                                                                 Name = "Statement",
                                                                 IsVisible = false,
                                                                 GoTo = "/Payments/Statement"
                                                             },
                                                new OperationStep
                                                             {Uid = "homeMenuItem", Name = "Back", GoTo = "/Home/Index"}
                                           };

        public PaymentsController()
        {
            var container = new IbsContainer();
            knowledgeBaseService = container.KnowledgeBaseService;
            this.authorityService = container.AuthorityService;
            this.accountService = container.AccountService;
            _transferService = container.TransferService;
            this.cardService = container.CardService;
            this.paymentService = container.PaymentService;
        }

        public ActionResult Index()
        {
            ViewBag.Steps = steps;
            ViewBag.ActiveStep = steps[0];

            var client = authorityService.GetClientByUserName(User.Identity.Name);

            IEnumerable<Card> cards = null;

            try
            {
                cards = cardService.GetClientsCard(client, c => !c.IsBlocked);
            }
            catch (BusinessException be)
            {
                ModelState.AddModelError("", be.Message);
            }

            //var profile = ProfileBase.Create(User.Identity.Name);

            ViewBag.SelectedCardIndex = "0";//Session["CardIndex"];
            ViewBag.AccountService = accountService;
            ViewBag.Payment = new PaymentModel();
            return View(cards);
        }

        [HttpPost]
        public ActionResult SelectPayment(PaymentModel payment)
        {

            //Session["CardIndex"] = "0";

            ViewBag.Steps = steps;
            steps[1].IsVisible = true;

            ViewBag.ActiveStep = steps[1];
            //Fix bug with detail filling after load quickPayment
            payment.PaymentDetail = "";
            ViewBag.Payment = payment;
            // ViewBag.EnsureSecurity = true;

            return View();
        }

        [HttpPost]
        public ActionResult Detail(PaymentModel payment)
        {
            ViewBag.Steps = steps;
            steps[1].IsVisible = true;
            steps[2].IsVisible = true;
            steps[3].IsVisible = true;
            ViewBag.ActiveStep = steps[2];
            ViewBag.EnsureSecurity = true;
            ViewBag.Payment = payment;
            return View();
        }

        [HttpPost]
        public ActionResult Bill(PaymentModel payment)
        {
            if (ModelState.IsValid)
            {
                ViewBag.Payment = payment;

            }
            return View();
        }
        [HttpPost]
        public ActionResult Statement(PaymentStatementModel statementModel)
        {
            if (statementModel.Page == null)
                statementModel.Page = 1;
            ViewBag.Steps = steps;
            steps[1].IsVisible = true;
            steps[2].IsVisible = true;
            steps[3].IsVisible = true;
            ViewBag.ActiveStep = steps[3];
            ViewBag.Payment = statementModel;
            if (statementModel.FromDate != null)
                ViewBag.FromDate = statementModel.FromDate.Value.ToString("MM/dd/yyyy");

            if (statementModel.ToDate != null)
                ViewBag.ToDate = statementModel.ToDate.Value.ToString("MM/dd/yyyy");

            int totalCount;
            IList<Transfer> model = PagingHelper.Paging<Transfer>(_transferService.GetTransfers,

                  t => (TransferType)t.TransferType == TransferType.ToPayment &&
                     t.ToPaymentId == statementModel.PaymentId &&

                     (!statementModel.FromDate.HasValue ||
                      statementModel.FromDate.HasValue && t.StartDate.Date >= statementModel.FromDate.Value.Date) &&

                     (!statementModel.ToDate.HasValue ||
                      statementModel.ToDate.HasValue && t.StartDate.Date <= statementModel.ToDate.Value.Date
                     ),
                     statementModel.Page.Value, out totalCount);


            ViewBag.CurrentPage = statementModel.Page;

            ViewBag.TotalRecordsCount = totalCount;
            return View(model.ToList());
        }

        #region Ajax

        private ActionResult AjaxSuccess()
        {
            return Content("{success:true, errorCode:-1,error:\"\"}", "json");
        }
        private ActionResult AjaxFail(string message)
        {
            return Content("{success:true, errorCode:1,error:\"" + message + "\"}", "json");
        }

        [HttpPost]
        public ActionResult Pay(PaymentModel payment)
        {
            Transfer transfer = null;
            if (ModelState.IsValid)
            {
                try
                {
                    transfer = paymentService.PayPayment(payment.CardNumber, payment.PaymentId, payment.PaymentDetail, payment.Amount,
                         payment.Currency, User.Identity.Name);
                }
                catch (BusinessException be)
                {
                    ModelState.AddModelError("", be.Message);
                    return AjaxFail(be.Message);
                }
            }
            ViewBag.Payment = payment;
            if (transfer != null)
                return Json(new
                {
                    success = true,
                    transferId = transfer.Id,
                    error = ""
                });
            //return Content("{success:true, transferId: " + transfer.Id + ", error:\"\"}", "json");
            else return AjaxFail("Can't pay");
        }

        public ActionResult SaveQuickPayment(QuickPaymentModel payment)
        {
            var profile = ProfileBase.Create(User.Identity.Name);
            var model = (QuickPayments)profile["Drafts"];
            if (model.Count >= 4)
                return
                    Json(new
                             {
                                 success = false,
                                 error =
                             "Max count of QuickPayments is 4. Please delete at first any existing QuickPayment and try again",
                             });
            model.Add(new QuickPaymentModel()
            {
                CardNumber = payment.CardNumber,
                Name = payment.Name ?? "XXX",
                PaymentDetail = payment.PaymentDetail,
                PaymentId = payment.PaymentId

            });
            profile["Drafts"] = model;
            profile.Save();
            return Json(new { success = true });
        }

        [HttpGet]
        public ActionResult DeleteQuickPayment(int index)
        {
            var profile = ProfileBase.Create(User.Identity.Name);
            var model = (QuickPayments)profile["Drafts"];
            try
            {
                var quickPayment = model[index];
                model.Remove(quickPayment);
                profile["Drafts"] = model;
                profile.Save();
            }
            catch (Exception)
            {

            }
            return RedirectToAction("Index", "Home");
        }
        public ActionResult DetailJSON(int id, string cardNumber)
        {
            var p = new PaymentXmlBuilder();
            var payment = paymentService.GetPaymentById(id);
            var JSON = p.PaymentDetailJSON(payment, cardNumber);
            return Json(JSON);
        }


        public ActionResult Tree()
        {
            var p = new PaymentXmlBuilder();
            var EripPayments = paymentService.GetEripPayments();
            var NotEripPayments = paymentService.GetNotEripPayments();

            var eripXmlTree = "<group text='ERIP'>" + p.PaymentsTreeXml(EripPayments) + "</group>";
            var notEripXmlTree = "<group text='NOT ERIP'>" + p.PaymentsTreeXml(NotEripPayments) + "</group>";
            var resultXml = "<xml>" + eripXmlTree + notEripXmlTree + "</xml>";
            return this.Content(resultXml, "text/xml");
        }

        #endregion


    }

}
